<?php

/**
 * Boleto form.
 *
 * @package    SistemaRutasEc
 * @subpackage form
 * @author     Your name here
 * @version    SVN: $Id: sfDoctrineFormTemplate.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
 */
class BoletoForm extends BaseBoletoForm {

    public function configure() {
        $mes = date('m');
        $anio = date('y');
        $hoy = date('d');
        $range = range($hoy, date('t', mktime(0, 0, 0, $mes, 1, $anio)));
        $dias = array_combine($range, $range);

        $this->widgetSchema['dias'] = new sfWidgetFormChoice(array('choices' => $dias));
        $this->validatorSchema['dias'] = new sfValidatorChoice(array('choices' => $dias));
        $this->widgetSchema['dias']->setAttribute('id', 'dias');

        $this->widgetSchema['escala'] = new sfWidgetFormChoice(array('choices' => array('' => 'Seleccione una ruta')));
        $this->validatorSchema['escala'] = new sfValidatorPass();
        $this->widgetSchema['escala']->setAttribute('id', 'escala');

        $this->widgetSchema['asientos'] = new sfWidgetFormInput();
        $this->validatorSchema['asientos'] = new sfValidatorNumber(array('min' => 1, 'max' => Boleto::MAX_ASIENTOS));

        $this->validatorSchema['id_tu'] = new sfValidatorPass();
        $this->validatorSchema['dni'] = new sfValidatorPass();

        //formularios embebidos
        $turnoForm = new TurnoForm($this->getObject()->getTurno());
        $personaForm = new PersonaForm();

        unset($this['estado']);
        unset($this['origen']);

        unset($personaForm['email_address']);
        $personaForm->getValidatorSchema()->offsetSet('dni', new sfValidatorPass());
        $personaForm->getValidatorSchema()->setPostValidator(new sfValidatorPass()); //FIXME: BasePersonaForm - dni no debe ser primary key

        $this->embedForm('turno', $turnoForm);
        $this->embedForm('persona', $personaForm);
    }

    protected function doSave($con = null) {
        if (null === $con) {
            $con = $this->getConnection();
        }

        $regla = Doctrine_Query::create()
                ->from('regla r')
                ->where('r.id_co = ?', $this->values['turno']['id_co'])
                ->fetchOne();
        $frecuencia = Doctrine_Core::getTable('frecuencia')->find($this->values['turno']['id_fre']);
        $escala = Doctrine_Core::getTable($regla->especial ? 'escalaespecial' : 'escalanormal')->find($this->values['escala']);

        $fecha_turno = date('Y-m-d', mktime(0, 0, 0, date('n'), $this->values['dias'], date('Y')));

        $turno = Doctrine_Core::getTable('turno')->createQuery('t')
                ->where('t.id_ru = ?', $this->values['turno']['id_ru'])
                ->andwhere('t.id_fre = ?', $this->values['turno']['id_fre'])
                ->andWhere('t.fecha = ?', $fecha_turno)
                ->andWhere('t.id_co = ?', $this->values['turno']['id_co'])
                ->fetchOne();

        if (null == $turno) {
            throw new sfException('No existe un turno disponible', 1);
        }

        $persona = Doctrine_Query::create()
                ->from('persona p')
                ->where('p.dni = ?', $this->values['persona']['dni'])
                ->fetchOne();

        if (null == $persona) {
            $persona = new Persona();
            $persona->fromArray($this->values['persona']);
        }

        $boleto = $this->updateObject();
        $boleto->id_tu = $turno->id_tu;
        $boleto->setTurno($turno);
        $boleto->dni = $this->values['persona']['dni'];
        $boleto->destino = $escala->ciudad;
        $boleto->origen = Boleto::ORIGEN_VENTA;
        $boleto->estado = Boleto::VENDIDO;

        $table = BoletoTable::getInstance();

        $asientos_reserva = range(3, 32);
        $asientos_turno = $table->createQuery()
                ->from('Asiento a')
                ->leftJoin('a.Boleto r')
                ->where('r.id_tu = ?', $turno->id_tu)
                ->andWhere('r.estado = ? OR r.estado = ?', array(Boleto::RESERVADO, Boleto::VENDIDO))
                ->select('a.numero')
                ->orderBy('a.numero')
                ->execute(array(), Doctrine_Core::HYDRATE_SINGLE_SCALAR);

        if (!is_array($asientos_turno))
            $asientos_turno = array($asientos_turno);

        $asientos_disponibles = array_values(array_diff($asientos_reserva, $asientos_turno)); //FIXME

        if (count($asientos_disponibles) < $this->values['asientos']) {
            throw new sfException('No existen suficientes asientos disponibles', 1);
        }

        for ($i = 0; $i < $this->values['asientos']; $i++) {
            $asiento = new Asiento();
            $asiento->setNumero($asientos_disponibles[$i]);
            $asiento->setBoleto($boleto);
            $boleto->getAsientos()->add($asiento);
        }

        $boleto->valor = $this->values['asientos'] * ($frecuencia->especial ? $escala->costoespecial : $escala->costonormal);

        $cancelaciones = $table->obtenerReservaciones($this->values['persona']['dni'], Boleto::CANCELADO_RESERVACION);

        foreach ($cancelaciones as $item) {
            $boleto->valor += $item->valor * Boleto::RECARGO_CANCELACION;
            $item->estado = Boleto::CANCELADO_ABONADO;
        }

        $persona->save($con);
        $boleto->save($con);
        $cancelaciones->save($con);
    }

}
